package com.tinysand.advert.mysql;

import com.alibaba.fastjson.JSON;
import com.tinysand.advert.mysql.constant.OperationType;
import com.tinysand.advert.mysql.dto.ParseTemplate;
import com.tinysand.advert.mysql.dto.TableTemplate;
import com.tinysand.advert.mysql.dto.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author TINY
 */
@Slf4j
@Component
@SuppressWarnings("all")
public class TemplateHolder {
    private ParseTemplate template;
    private final JdbcTemplate jdbcTemplate;
    private String SQL_SCHEMA = new String(
            "select table_schema,table_name, column_name, " +
                    "ordinal_position form information_schema.columns " +
                    "where table_schema = ? and table_name = ?");

    @Autowired
    public TemplateHolder(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

//    @PostConstruct
    public void initial() { loadJson("template.json"); }

    public TableTemplate getTable(String tableName) {
        return template.getTableTemplateMap().get(tableName);
    }

    private void loadMetaData() {

        for (Map.Entry<String, TableTemplate> entry :
                template.getTableTemplateMap().entrySet()) {
            TableTemplate table = entry.getValue();
            List<String> updateFields = table.getOpTypeFieldMap().get(
                    OperationType.UPDATE
            );

            List<String> insertFields = table.getOpTypeFieldMap().get(
                    OperationType.ADD
            );

            List<String> deleteFields = table.getOpTypeFieldMap().get(
                    OperationType.DELETE
            );

            jdbcTemplate.query(SQL_SCHEMA, new Object[]{
                    template.getDatabase(), table.getTableName()
            }, (rs, i) -> {
                int pos = rs.getInt("ORDINAL_POSITION");
                String columnName = rs.getString("COLUMN_NAME");
                if ((null != updateFields && updateFields.contains(columnName))
                        || (null != insertFields
                        && insertFields.contains(columnName))
                        || (null != deleteFields
                        && deleteFields.contains(columnName))) {
                    table.getPosMap().put(pos - 1, columnName);
                }
                return null;
            });
        }
    }

    private void loadJson(String path) {
        InputStream inputStream = Thread.currentThread()
                .getContextClassLoader().getResourceAsStream(path);
        try {
            Template template = JSON.parseObject(
                    Objects.requireNonNull(inputStream),
                    Charset.defaultCharset(), Template.class
            );
            this.template = ParseTemplate.parseTemplate(template);
            loadMetaData();
        } catch (IOException ex) {
            log.error("无法读取JSON文件，{}", ex.getMessage());
        }
    }
}
